package ba.keco.hbase.lib;

import java.io.IOException;
import java.util.Random;
import java.util.UUID;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;

public class Util {

	public static void createTable(String name, int numOfColumnFamilies, String columnFamilyName) throws IOException {
		Configuration conf = HBaseConfiguration.create();

		HBaseAdmin admin = new HBaseAdmin(conf);

		HTableDescriptor descriptor = new HTableDescriptor(name);

		for (int i = 0; i < numOfColumnFamilies; i++) {
			HColumnDescriptor cf = new HColumnDescriptor(columnFamilyName + i);
			descriptor.addFamily(cf);
		}

		admin.createTable(descriptor);
	}

	public static void createTableVersions(String name, int numOfColumnFamilies, int versions) throws IOException {
		createTable(name, numOfColumnFamilies, 65536, versions);
	}

	public static void createTable(String name, int numOfColumnFamilies, int blockSize) throws IOException {
		createTable(name, numOfColumnFamilies, blockSize, 3);
	}

	public static void createTable(String name, int numOfColumnFamilies, int blockSize, int versions) throws IOException {
		Configuration conf = HBaseConfiguration.create();

		HBaseAdmin admin = new HBaseAdmin(conf);

		HTableDescriptor descriptor = new HTableDescriptor(name);

		for (int i = 0; i < numOfColumnFamilies; i++) {
			HColumnDescriptor cf = new HColumnDescriptor("cf" + i);
			cf.setBlocksize(blockSize);
			cf.setMaxVersions(versions);
			descriptor.addFamily(cf);
		}

		admin.createTable(descriptor);
	}

	public static void createTable(String name, int numOfColumnFamilies) throws IOException {
		createTable(name, numOfColumnFamilies, 65536);
	}

	public static void delete(String name) throws IOException {
		Configuration conf = HBaseConfiguration.create();

		HBaseAdmin admin = new HBaseAdmin(conf);

		admin.disableTable(name);
		admin.deleteTable(name);
	}

	public static Put generateRecordLong(int numOfColumnFamilies, int qualifiersPerColumnFamily) {
		long random = generateRandom();

		Put p = new Put(Bytes.toBytes(random));

		for (int i = 0; i < numOfColumnFamilies; i++) {
			for (int j = 0; j < qualifiersPerColumnFamily; j++) {
				p.add(Bytes.toBytes("cf" + i), Bytes.toBytes("q" + j), Bytes.toBytes(random));
			}
		}
		return p;
	}

	public static long generateRandom() {
		Random r = new Random();
		long number = (long) (r.nextDouble() * Long.MAX_VALUE);
		return number;
	}

	public static long generateRandom(long maxValue) {
		Random r = new Random();
		long number = (long) (r.nextDouble() * maxValue);
		return number;
	}

	public static Put generateRecordString(int numOfColumnFamilies, int qualifiersPerColumnFamily) {
		long random = generateRandom();

		Put p = new Put(Bytes.toBytes(String.valueOf(random)));

		for (int i = 0; i < numOfColumnFamilies; i++) {
			for (int j = 0; j < qualifiersPerColumnFamily; j++) {
				p.add(Bytes.toBytes("cf" + i), Bytes.toBytes("q" + j), Bytes.toBytes(String.valueOf(random)));
			}
		}
		return p;
	}

	public static Put generateRecord(int numOfColumnFamilies, int qualifiersPerColumnFamily) {
		String uuid = UUID.randomUUID().toString();
		return generateRecord(uuid, numOfColumnFamilies, qualifiersPerColumnFamily);
	}

	public static Put generateRecord(int numOfColumnFamilies, int qualifiersPerColumnFamily, String columnFamily, String qualifier) {
		String uuid = UUID.randomUUID().toString();
		return generateRecord(uuid, numOfColumnFamilies, qualifiersPerColumnFamily, columnFamily, qualifier);
	}

	public static Put generateRecord(String rowkey, int numOfColumnFamilies, int qualifiersPerColumnFamily) {
		return generateRecord(rowkey, numOfColumnFamilies, qualifiersPerColumnFamily, "cf", "q");
	}

	public static Put generateRecord(String rowkey, int numOfColumnFamilies, int qualifiersPerColumnFamily, String columnFamily, String qualifier) {
		Put p = new Put(Bytes.toBytes(rowkey));

		for (int i = 0; i < numOfColumnFamilies; i++) {
			for (int j = 0; j < qualifiersPerColumnFamily; j++) {
				p.add(Bytes.toBytes(columnFamily + i), Bytes.toBytes(qualifier + j), Bytes.toBytes(UUID.randomUUID().toString()));
			}
		}
		return p;
	}

	public static Put generateRecord(int numOfColumnFamilies, int qualifiersPerColumnFamily, int versions) {
		return generateRecord(UUID.randomUUID().toString(), numOfColumnFamilies, qualifiersPerColumnFamily, versions);
	}

	public static Put generateRecord(String rowkey, int numOfColumnFamilies, int qualifiersPerColumnFamily, int versions) {
		Put p = new Put(Bytes.toBytes(rowkey));

		for (int i = 0; i < numOfColumnFamilies; i++) {
			for (int j = 0; j < qualifiersPerColumnFamily; j++) {
				for (int k = 0; k < versions; k++) {
					long version = generateRandom(System.currentTimeMillis());
					p.add(Bytes.toBytes("cf" + i), Bytes.toBytes("q" + j), version, Bytes.toBytes(UUID.randomUUID().toString()));
				}
			}
		}
		return p;
	}
}
